package com.ys.job.btc;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.ys.entity.WalletAddress;
import com.ys.entity.WalletDeposit;
import com.ys.entity.WalletScanBlock;
import com.ys.entity.WalletWithdraw;
import com.ys.entity.block.Transaction;
import com.ys.entity.block.btc.BtcAccountTransatcion;
import com.ys.entity.block.btc.BtcTransation;
import com.ys.entity.block.btc.ValidateAddressInfo;
import com.ys.enu.CurrencyEnum;
import com.ys.exception.base.BizException;
import com.ys.service.WalletAddressServiceImap;
import com.ys.service.WalletDepositServiceImap;
import com.ys.service.WalletScanBlockServiceImap;
import com.ys.service.WalletWithdrawServiceImap;
import com.ys.service.wallet.AbstractWalletJobService;
import com.ys.service.wallet.WalletServicceContext;
import com.ys.service.wallet.btc.BtcService;
import com.ys.service.wallet.btc.BtcWalletService;
import com.ys.util.HexUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import sun.util.resources.cldr.uk.CurrencyNames_uk;

import java.math.BigDecimal;
import java.util.List;

/**
 * 比特系定时任务
 *
 */
@Component
@Data
@Slf4j
public class BtcWalletJob  {

    public static String RECEIVE="RECEIVE";
    @Autowired
    private WalletAddressServiceImap walletAddressServiceImap;
    @Autowired
    private WalletServicceContext walletServicceContext;
    @Autowired
    private BtcService btcService;

    @Autowired
    private WalletDepositServiceImap walletDepositServiceImap;
    @Autowired
    private WalletWithdrawServiceImap walletWithdrawServiceImap;
    @Autowired
    private BtcWalletService btcWalletService;


    @Autowired
    private WalletScanBlockServiceImap walletScanBlockServiceImap;

    /**
     * 自动设置address的公钥
     */
    @Scheduled(cron = "17 * * * * ?")
    public void updateAddressPubkey(){
        log.info("比特系Adress设置pubkey任务 start");
        EntityWrapper<WalletAddress> ew=new EntityWrapper<>();

        ew.isNull("pubKey");
        /**比特币链类型**/
        ew.eq("currencyChainType", CurrencyEnum.BTC.currencyChainType);

        List<WalletAddress> list=walletAddressServiceImap.selectList(ew);
        if(CollUtil.isEmpty(list)){
            log.info("比特系address设置prikey任务为空");
            return;
        }
        for(WalletAddress walletAddress:list){
            /****/
            BtcWalletService walletService=walletServicceContext.getWalletBtcRPC(walletAddress.getCurrency());
            ValidateAddressInfo validateAddressInfo=walletService.validAddress(walletAddress.getAdress());
            if(validateAddressInfo==null || !validateAddressInfo.isIsvalid()){
                log.warn("比特系地址查询pubkey失败："+ JSONUtil.toJsonStr(validateAddressInfo));
                continue;
            }

            WalletAddress walletAddressPubkey=new WalletAddress();
            walletAddressPubkey.setId(walletAddress.getId());
            walletAddressPubkey.setPubKey(validateAddressInfo.getPubkey());
            walletAddressServiceImap.updateById(walletAddressPubkey);

        }
        log.info("比特系Adress设置pubkey任务 end");

    }

    /**
     * 自动设置address的私钥
     */
    @Scheduled(cron = "19 * * * * ?")
    public void updateAddressPrikey(){
        log.info("比特系Adress设置prikey任务 start");
        EntityWrapper<WalletAddress> ew=new EntityWrapper<>();

        ew.isNull("priKey");
        /**比特币链类型**/
        ew.eq("currencyChainType", CurrencyEnum.BTC.currencyChainType);

        List<WalletAddress> list=walletAddressServiceImap.selectList(ew);
        if(CollUtil.isEmpty(list)){
            log.info("比特系address设置prikey任务为空");
            return;
        }
        for(WalletAddress walletAddress:list){
            /****/
            BtcWalletService walletService=walletServicceContext.getWalletBtcRPC(walletAddress.getCurrency());

            String prikey=walletService.queryPrikeyByAddress(walletAddress.getAdress());
            if(StrUtil.isEmpty(prikey)){
                log.warn("比特系地址查询prikey失败："+ JSONUtil.toJsonStr(walletAddress));
                continue;
            }

            WalletAddress walletAddressPrikey=new WalletAddress();
            walletAddressPrikey.setId(walletAddress.getId());
            walletAddressPrikey.setPriKey(prikey);
            walletAddressServiceImap.updateById(walletAddressPrikey);

        }
        log.info("比特系Adress设置prikey任务 end");
    }

    /**
     *
     * 更新冲提交易状态
     */
    @Scheduled(cron = "22 * * * * ?")
    public void confirmDepositeWithdrawStatus(){
        log.info("比特币更新充提任务 start!");


        /**查询连上的最新区块数**/
        String blockNum=btcWalletService.mostRecentBlockNumber();

        if(StrUtil.isBlank(blockNum)){
            log.warn("比特系确认充值查询块号失败！");
            return ;
        }
        btcService.updateDepositWithdrawStatus(Integer.parseInt(blockNum));

        log.info("比特币更新充提任务 end!");
    }

    /**
     * 比特币充值扫描
     */
    @Scheduled(cron = "0/1 * * * * ?")
    public void deposite() throws BizException {
        log.info("比特币充值扫描任务任务 start");
        EntityWrapper<WalletScanBlock> ew=new EntityWrapper();
        ew.eq("currencyChainType", CurrencyEnum.BTC.currencyChainType);
        WalletScanBlock walletScanBlock=walletScanBlockServiceImap.selectOne(ew);

        if(walletScanBlock==null || walletScanBlock.getBlockNum()==null){
            log.warn("比特币充值扫描 数据库配置错误。 end");
            return;
        }
        int i=walletScanBlock.getBlockNum();
        List<BtcAccountTransatcion>  list=btcWalletService.listtransactions(btcWalletService.getDepositAddress(),i);
        if(CollUtil.isEmpty(list)){
            log.warn("比特币 账户查询充值记录为空：address"+btcWalletService.getDepositAddress());
            return;
        }

        for(BtcAccountTransatcion btcAccountTransatcion:list){
            i++;
            if(!btcAccountTransatcion.getCategory().toUpperCase().equals(RECEIVE)){
                log.info("比特币充值扫描此笔交易类型是send,send="+btcAccountTransatcion.getCategory());
                continue;
            }

            /**根据txId查询交易的toaddress 是否在钱包内**/
            /**判断是否是平台的address 原则上应该都是**/
            EntityWrapper<WalletAddress> entityWrapper=new EntityWrapper<>();
            entityWrapper.ne("adress",btcAccountTransatcion.getAddress());
            entityWrapper.ne("currencyChainType",CurrencyEnum.BTC.currencyChainType);
            List walletAddressList=walletAddressServiceImap.selectList(entityWrapper);
            if(CollUtil.isEmpty(walletAddressList)){
                log.warn("比特币扫描充值记录 此地址不在钱包内：address="+"address");
                continue;

            }
            btcService.dealDepositeTransaction(btcAccountTransatcion);
            /**更新扫描块号**/

            WalletScanBlock updateWallScanBlock=new WalletScanBlock();
            updateWallScanBlock.setId(walletScanBlock.getId());
            updateWallScanBlock.setBlockNum(i);
            walletScanBlockServiceImap.updateById(updateWallScanBlock);
        }

        log.info("比特币充值扫描任务任务 end");

    }




}
